package com.jiangxiaofei.citycloud.activity.video;


import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.os.Bundle;
import android.os.Looper;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.PopupWindow;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Spinner;

import com.company.CodecSDK.AAC_ENC_Format;
import com.company.CodecSDK.AudioBuf;
import com.company.CodecSDK.ICodecSDK;
import com.company.CodecSDK.Setformat;
import com.company.NetSDK.AV_CFG_ChannelVideoColor;
import com.company.NetSDK.CB_fDisConnect;
import com.company.NetSDK.CB_fHaveReConnect;
import com.company.NetSDK.CB_fMessageCallBack;
import com.company.NetSDK.CB_fRealDataCallBackEx;
import com.company.NetSDK.CB_fRealPlayDisConnect;
import com.company.NetSDK.CB_fSnapRev;
import com.company.NetSDK.CB_fSubDisConnect;
import com.company.NetSDK.CB_pfAudioDataCallBack;
import com.company.NetSDK.CFG_CAP_ALARM_INFO;
import com.company.NetSDK.CFG_DSPENCODECAP_INFO;
import com.company.NetSDK.CFG_FLASH_LIGHT;
import com.company.NetSDK.DEV_PLAY_RESULT;
import com.company.NetSDK.EM_USEDEV_MODE;
import com.company.NetSDK.FinalVar;
import com.company.NetSDK.INetSDK;
import com.company.NetSDK.LOG_SET_PRINT_INFO;
import com.company.NetSDK.NET_DEVICEINFO;
import com.company.NetSDK.NET_IN_MEMBERNAME;
import com.company.NetSDK.NET_OUT_MEMBERNAME;
import com.company.NetSDK.NET_PARAM;
import com.company.NetSDK.NET_SPEAK_PARAM;
import com.company.NetSDK.NET_TALK_TRANSFER_PARAM;
import com.company.NetSDK.SDKDEV_DSP_ENCODECAP_EX;
import com.company.NetSDK.SDKDEV_TALKFORMAT_LIST;
import com.company.NetSDK.SDK_DEV_ENABLE_INFO;
import com.company.NetSDK.SDK_DEV_FUNC;
import com.company.NetSDK.SDK_EXTPTZ_ControlType;
import com.company.NetSDK.SDK_PRODUCTION_DEFNITION;
import com.company.NetSDK.SDK_PTZ_ControlType;
import com.company.NetSDK.SDK_RealPlayType;
import com.company.NetSDK.SDK_SYS_ABILITY;
import com.company.NetSDK.SDK_TALK_CODING_TYPE;
import com.company.NetSDK.SNAP_PARAMS;
import com.company.PlaySDK.Constants;
import com.company.PlaySDK.IPlaySDK;
import com.company.PlaySDK.IPlaySDKCallBack;
import com.company.PlaySDK.IPlaySDKCallBack.DEMUX_INFO;
import com.company.PlaySDK.IPlaySDKCallBack.fDemuxCBFun;
import com.jiangxiaofei.citycloud.R;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

public class LiveActivity extends Activity {
    SurfaceView m_PlayView;

    Button m_btStartRecord;
    Button m_btEncode;
    Button m_btSound;
    Button m_btCapture;

    Spinner m_spStream;
    ArrayList<String> alStream = new ArrayList<String>();

    // Flash related
    Button m_btFlash;
    View m_layoutFlash;
    PopupWindow m_popFlash;
    CFG_FLASH_LIGHT stFlash = new CFG_FLASH_LIGHT();

    // PTZ
    Button m_btPtz;
    View m_layoutPtz;
    PopupWindow m_popPtz;

    Button bt_end_talk;
    // volume
    Button m_btVolume;
    View m_LayoutVolume;
    PopupWindow m_popVolume;
    private int nCurVolume = -1;

    // quality
    Button m_btQuality;
    View m_layoutQuality;
    PopupWindow m_popQuality;

    // remote snap
    Button m_btSnap;
    boolean bSnapCbSet = false;

    Resources res;

    private static String[] m_strSpeed;
    byte m_bSpeed = 5;

    private static String[] m_strStream;

    TestRealDataCallBackEx m_callback = new TestRealDataCallBackEx();
    TestVideoDataCallBack m_VideoCallback = new TestVideoDataCallBack();

    static int nPort = IPlaySDK.PLAYGetFreePort();
    static FileOutputStream m_Fout;

    static long lRealHandle = 0;

    private boolean bRecordFlag = false;
    private boolean bSound = true;
    private SurfaceHolder holder;
    private int nExtraChnNum;

    int m_nGlobalChn = 0;
    int m_nGlobalPbStream = 0;
    private int nDevPort;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_liveview);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        INetSDK.LoadLibrarys();

        LOG_SET_PRINT_INFO logInfo = new LOG_SET_PRINT_INFO();
        logInfo.bSetFilePath = true;
        INetSDK.LogOpen(logInfo);

        DeviceDisConnect disConnect = new DeviceDisConnect();
        INetSDK.Init(disConnect);

        INetSDK.SetConnectTime(4000, 3);
        NET_PARAM stNetParam = new NET_PARAM();
        stNetParam.nWaittime = 3000;
        stNetParam.nSearchRecordTime = 30000;
        INetSDK.SetNetworkParam(stNetParam);
        login();
        INetSDK.QueryDevState(m_loginHandle, FinalVar.SDK_DEVSTATE_TALK_ECTYPE,
                m_TalkFormatList, 4000);
        res = this.getResources();
        m_strSpeed = new String[]{res.getString(R.string.live_activity_speed_1), res.getString(R.string.live_activity_speed_2),
                res.getString(R.string.live_activity_speed_3), res.getString(R.string.live_activity_speed_4), res.getString(R.string.live_activity_speed_5),
                res.getString(R.string.live_activity_speed_6), res.getString(R.string.live_activity_speed_7), res.getString(R.string.live_activity_speed_8)};
        m_strStream = new String[]{res.getString(R.string.stream_master), res.getString(R.string.stream_sub1),
                res.getString(R.string.stream_sub2), res.getString(R.string.stream_sub3)};

        m_PlayView = (SurfaceView) findViewById(R.id.view_PlayWindow);
        holder = m_PlayView.getHolder();
        holder.addCallback(new Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                Log.d("[playsdk]surface", "surfaceCreated");
                IPlaySDK.InitSurface(nPort, m_PlayView);
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width,
                                       int height) {
                Log.d("[playsdk]surface", "surfaceChanged");
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                Log.d("[playsdk]surface", "surfaceDestroyed");
            }
        });

        m_btFlash = (Button) findViewById(R.id.bt_flash);
        m_btFlash.setOnClickListener(new LiveButtonsListener());
        if (!stCfgCapAlarm.bFlashLight) {
            m_btFlash.setEnabled(false);
        }

        m_btPtz = (Button) findViewById(R.id.bt_ptz);
        m_btPtz.setOnClickListener(new LiveButtonsListener());

        m_btStartRecord = (Button) findViewById(R.id.button_startRecord);
        m_btStartRecord.setOnClickListener(new LiveButtonsListener());

        m_btVolume = (Button) findViewById(R.id.bt_live_volume);
        m_btVolume.setOnClickListener(new LiveButtonsListener());

        m_btEncode = (Button) findViewById(R.id.bt_encode);
        m_btEncode.setOnClickListener(new LiveButtonsListener());

        m_btQuality = (Button) findViewById(R.id.bt_live_quality);
        m_btQuality.setOnClickListener(new LiveButtonsListener());

        m_layoutFlash = View.inflate(LiveActivity.this, R.layout.flashconfigview, null);
        m_layoutPtz = View.inflate(LiveActivity.this, R.layout.ptzview, null);
        m_LayoutVolume = View.inflate(LiveActivity.this, R.layout.volumeview, null);
        m_layoutQuality = View.inflate(LiveActivity.this, R.layout.qualityview, null);

        m_btSound = (Button) findViewById(R.id.bt_sound);
        m_btSound.setOnClickListener(new LiveButtonsListener());

        m_btCapture = (Button) findViewById(R.id.bt_live_capture);
        m_btCapture.setOnClickListener(new LiveButtonsListener());

        m_spStream = (Spinner) findViewById(R.id.sp_live_stream);

        m_btSnap = (Button) findViewById(R.id.bt_live_snap);
        m_btSnap.setOnClickListener(new LiveButtonsListener());

        bt_end_talk = (Button) findViewById(R.id.bt_end_talk);
        bt_end_talk.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                stopTalk();
            }
        });
        new Thread(new Runnable() {
            @Override
            public void run() {
                Looper.prepare();

                if (StartRealPlay(SDK_RealPlayType.SDK_RType_Realplay) == true) {
                    m_callback = new TestRealDataCallBackEx();
                    m_VideoCallback = new TestVideoDataCallBack();

                    if (lRealHandle != 0) {
                        INetSDK.SetRealDataCallBackEx(lRealHandle, m_callback, 1);
                    }
                }
                Looper.loop();
            }
        }).start();

        int nStreaMask = 0;
        if (0 == nStreaMask) {
            SDKDEV_DSP_ENCODECAP_EX stEncodeCapOld = new SDKDEV_DSP_ENCODECAP_EX();
            CFG_DSPENCODECAP_INFO stEncodeCapNew = new CFG_DSPENCODECAP_INFO();
            if (INetSDK.QueryDevState(m_loginHandle, FinalVar.SDK_DEVSTATE_DSP_EX, stEncodeCapOld, 6000)) {
                nStreaMask = stEncodeCapOld.dwStreamCap;
            } else if (ToolKits.GetDevConfig(FinalVar.CFG_CMD_HDVR_DSP, stEncodeCapNew, m_loginHandle, m_nGlobalChn, 1024 * 70)) {
                nStreaMask = stEncodeCapNew.dwStreamCap;
            }
        }

        for (int i = 0; i < 4; i++) {
            if ((nStreaMask & (0x01 << i)) != 0) {
                alStream.add(m_strStream[i]);
            }
        }
        ArrayAdapter<String> aaStream = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, alStream);
        m_spStream.setAdapter(aaStream);
        if (!aaStream.isEmpty()) {
            m_spStream.setSelection(0, true);
        }
        m_spStream.setOnItemSelectedListener(new Spinner.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                StopRealPlay();

                int nType = 0;
                for (int i = 0; i < m_strStream.length; i++) {
                    if (m_strStream[i].equals(alStream.get(position))) {
                        nType = i;
                    }
                }

                if (StartRealPlay(SDK_RealPlayType.SDK_RType_Realplay_0 + nType) == true) {
                    m_callback = new TestRealDataCallBackEx();
                    m_VideoCallback = new TestVideoDataCallBack();

                    if (lRealHandle != 0) {
                        INetSDK.SetRealDataCallBackEx(lRealHandle, m_callback, 1);


                        // if silent, close sound
                        if (!bSound) {
                            int ret = IPlaySDK.PLAYStopSoundShare(nPort);
                        }
                    }
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });
    }

    public boolean StartRealPlay(int nStreamType) {
        lRealHandle = INetSDK.RealPlayEx(m_loginHandle, m_nGlobalChn, nStreamType);

        if (lRealHandle == 0) {
            ToolKits.showErrorMessage(LiveActivity.this, "RealPlayEx " + res.getString(R.string.info_failed));
            return false;
        }

        boolean bOpenRet = IPlaySDK.PLAYOpenStream(nPort, null, 0, 1024 * 1024 * 2) == 0 ? false : true;
        if (bOpenRet) {
            boolean bPlayRet = IPlaySDK.PLAYPlay(nPort, m_PlayView) == 0 ? false : true;
            if (bPlayRet) {
                boolean bSuccess = IPlaySDK.PLAYPlaySoundShare(nPort) == 0 ? false : true;
                if (!bSuccess) {
                    IPlaySDK.PLAYStop(nPort);
                    IPlaySDK.PLAYCloseStream(nPort);
                    return false;
                }

                if (-1 == nCurVolume) {
                    nCurVolume = IPlaySDK.PLAYGetVolume(nPort);
                } else {
                    IPlaySDK.PLAYSetVolume(nPort, nCurVolume);
                }
            } else {
                IPlaySDK.PLAYCloseStream(nPort);
                return false;
            }
        } else {
            return false;
        }

        return true;
    }

    public void StopRealPlay() {
        try {
            IPlaySDK.PLAYStop(nPort);
            IPlaySDK.PLAYStopSoundShare(nPort);
            IPlaySDK.PLAYCloseStream(nPort);

            if (bRecordFlag) {
                INetSDK.StopSaveRealData(lRealHandle);
                bRecordFlag = false;
                m_btStartRecord.setText(R.string.live_activity_start);
            }

            INetSDK.StopRealPlayEx(lRealHandle);

            if (null != m_Fout) {
                m_Fout.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        lRealHandle = 0;
    }

    private void flashProcess() {
        if (null != m_popPtz && m_popPtz.isShowing()) {
            m_popPtz.dismiss();
        }

        if (null != m_popVolume && m_popVolume.isShowing()) {
            m_popVolume.dismiss();
        }

        if (null != m_popQuality && m_popQuality.isShowing()) {
            m_popQuality.dismiss();
        }

        if (null == m_popFlash) {
            m_popFlash = new PopupWindow(m_layoutFlash, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        }

        if (m_popFlash.isShowing()) {
            m_popFlash.dismiss();
            return;
        } else {
            m_popFlash.showAtLocation(findViewById(R.id.live_view), Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 150);
        }

        CheckBox m_cbFlashEnable;
        SeekBar m_sbBright;

        m_cbFlashEnable = (CheckBox) m_layoutFlash.findViewById(R.id.cb_flash_enable);
        m_sbBright = (SeekBar) m_layoutFlash.findViewById(R.id.sb_bright);
        m_sbBright.setMax(100);
        m_sbBright.incrementProgressBy(1);

        boolean zRet = ToolKits.GetDevConfig(FinalVar.CFG_CMD_FLASH, stFlash, m_loginHandle, m_nGlobalChn, 4096);
        if (zRet) {
            m_cbFlashEnable.setChecked(stFlash.bEnable);
            m_sbBright.setProgress(stFlash.nBrightness);
        } else {
            ToolKits.showErrorMessage(LiveActivity.this, "GetDevConfig " + res.getString(R.string.info_failed));
            return;
        }

        m_cbFlashEnable.setOnCheckedChangeListener(new OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    stFlash.bEnable = true;
                } else {
                    stFlash.bEnable = false;
                }
                ToolKits.SetDevConfig(FinalVar.CFG_CMD_FLASH, stFlash, m_loginHandle, m_nGlobalChn, 4096);
            }
        });

        m_sbBright.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if (fromUser) {
                    stFlash.nBrightness = progress;
                    ToolKits.SetDevConfig(FinalVar.CFG_CMD_FLASH, stFlash, m_loginHandle, m_nGlobalChn, 4096);
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
    }

    private void ptzProcess() {
        if (null != m_popFlash && m_popFlash.isShowing()) {
            m_popFlash.dismiss();
        }

        if (null != m_popVolume && m_popVolume.isShowing()) {
            m_popVolume.dismiss();
        }

        if (null != m_popQuality && m_popQuality.isShowing()) {
            m_popQuality.dismiss();
        }

        if (null == m_popPtz) {
            m_popPtz = new PopupWindow(m_layoutPtz, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        }

        if (m_popPtz.isShowing()) {
            m_popPtz.dismiss();
            return;
        } else {
            m_popPtz.showAtLocation(findViewById(R.id.live_view), Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 150);
        }

        Button m_btUp;
        Button m_btDown;
        Button m_btRight;
        Button m_btLeft;
        Button m_btLUp;
        Button m_btRUp;
        Button m_btLDown;
        Button m_btRDown;
        Button m_btMore;
        Button m_btZoomA;
        Button m_btZoomD;
        Button m_btFocusA;
        Button m_btFocusD;
        Button m_btApertA;
        Button m_btApertD;
        Spinner m_spSpeed;

        m_btUp = (Button) m_layoutPtz.findViewById(R.id.btn_up);
        m_btUp.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return PTZControl(event, m_nGlobalChn, SDK_PTZ_ControlType.SDK_PTZ_UP_CONTROL, (byte) 0, m_bSpeed);
            }
        });

        m_btDown = (Button) m_layoutPtz.findViewById(R.id.btn_down);
        m_btDown.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return PTZControl(event, m_nGlobalChn, SDK_PTZ_ControlType.SDK_PTZ_DOWN_CONTROL, (byte) 0, m_bSpeed);
            }
        });

        m_btLeft = (Button) m_layoutPtz.findViewById(R.id.btn_left);
        m_btLeft.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return PTZControl(event, m_nGlobalChn, SDK_PTZ_ControlType.SDK_PTZ_LEFT_CONTROL, (byte) 0, m_bSpeed);
            }
        });

        m_btRight = (Button) m_layoutPtz.findViewById(R.id.btn_right);
        m_btRight.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return PTZControl(event, m_nGlobalChn, SDK_PTZ_ControlType.SDK_PTZ_RIGHT_CONTROL, (byte) 0, m_bSpeed);
            }
        });

        m_btLUp = (Button) m_layoutPtz.findViewById(R.id.btn_lup);
        m_btLUp.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return PTZControl(event, m_nGlobalChn, SDK_EXTPTZ_ControlType.SDK_EXTPTZ_LEFTTOP, m_bSpeed, m_bSpeed);
            }
        });

        m_btRUp = (Button) m_layoutPtz.findViewById(R.id.btn_rup);
        m_btRUp.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return PTZControl(event, m_nGlobalChn, SDK_EXTPTZ_ControlType.SDK_EXTPTZ_RIGHTTOP, m_bSpeed, m_bSpeed);
            }
        });

        m_btLDown = (Button) m_layoutPtz.findViewById(R.id.btn_ldown);
        m_btLDown.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return PTZControl(event, m_nGlobalChn, SDK_EXTPTZ_ControlType.SDK_EXTPTZ_LEFTDOWN, m_bSpeed, m_bSpeed);
            }
        });

        m_btRDown = (Button) m_layoutPtz.findViewById(R.id.btn_rdown);
        m_btRDown.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return PTZControl(event, m_nGlobalChn, SDK_EXTPTZ_ControlType.SDK_EXTPTZ_RIGHTDOWN, m_bSpeed, m_bSpeed);
            }
        });

        m_btMore = (Button) m_layoutPtz.findViewById(R.id.btn_more);
        m_btMore.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                //ToolKits.showMessage(v.getContext(), "Hit More");
                //Jump to another Activity to more ptz operation
            }
        });
        m_spSpeed = (Spinner) m_layoutPtz.findViewById(R.id.sp_speed);
        ArrayAdapter<String> apData = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, m_strSpeed);
        m_spSpeed.setAdapter(apData);
        m_spSpeed.setPrompt(res.getString(R.string.live_activity_speed_prom));
        m_spSpeed.setSelection(m_bSpeed - 1);
        m_spSpeed.setOnItemSelectedListener(new Spinner.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view,
                                       int position, long id) {
                m_bSpeed = (byte) (position + 1);
            }

            @Override
            public void onNothingSelected(AdapterView<?> arg0) {
            }
        });

        m_btZoomA = (Button) m_layoutPtz.findViewById(R.id.btn_z_add);
        m_btZoomA.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return PTZControl(event, m_nGlobalChn, SDK_PTZ_ControlType.SDK_PTZ_ZOOM_ADD_CONTROL, (byte) 0, m_bSpeed);
            }
        });

        m_btZoomD = (Button) m_layoutPtz.findViewById(R.id.btn_z_dec);
        m_btZoomD.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return PTZControl(event, m_nGlobalChn, SDK_PTZ_ControlType.SDK_PTZ_ZOOM_DEC_CONTROL, (byte) 0, m_bSpeed);
            }
        });

        m_btFocusA = (Button) m_layoutPtz.findViewById(R.id.btn_f_add);
        m_btFocusA.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return PTZControl(event, m_nGlobalChn, SDK_PTZ_ControlType.SDK_PTZ_FOCUS_ADD_CONTROL, (byte) 0, m_bSpeed);
            }
        });

        m_btFocusD = (Button) m_layoutPtz.findViewById(R.id.btn_f_dec);
        m_btFocusD.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return PTZControl(event, m_nGlobalChn, SDK_PTZ_ControlType.SDK_PTZ_FOCUS_DEC_CONTROL, (byte) 0, m_bSpeed);
            }
        });

        m_btApertA = (Button) m_layoutPtz.findViewById(R.id.btn_a_add);
        m_btApertA.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return PTZControl(event, m_nGlobalChn, SDK_PTZ_ControlType.SDK_PTZ_APERTURE_ADD_CONTROL, (byte) 0, m_bSpeed);
            }
        });

        m_btApertD = (Button) m_layoutPtz.findViewById(R.id.btn_a_dec);
        m_btApertD.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return PTZControl(event, m_nGlobalChn, SDK_PTZ_ControlType.SDK_PTZ_APERTURE_DEC_CONTROL, (byte) 0, m_bSpeed);
            }
        });
    }

    public class TestVideoDataCallBack implements fDemuxCBFun {
        @Override
        public void invoke(int nPort, byte[] pOrgBuffer, int nOrgLen,
                           byte[] pBuffer, int nLen, DEMUX_INFO stInfo, long dwUser) {
            try {
                if (null != m_Fout) {
                    m_Fout.write(pBuffer);
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }

    public class TestRealDataCallBackEx implements CB_fRealDataCallBackEx {
        @Override
        public void invoke(long lRealHandle, int dwDataType, byte[] pBuffer,
                           int dwBufSize, int param) {
            if (0 == dwDataType) {
                IPlaySDK.PLAYInputData(nPort, pBuffer, pBuffer.length);
            }
        }
    }

    public void StartRecord() {
        if (0 != lRealHandle) {
            if (!bRecordFlag) {
                // Do confirm the file path is exist, and APP has permission to access, otherwise will failed
                String filePath = "/mnt/sdcard/NetSDK/RealData.dav";
                if (createFile("/mnt/sdcard/NetSDK/", "RealData.dav")) {
                    boolean zRet = INetSDK.SaveRealData(lRealHandle, filePath);
                    if (!zRet) {
                        ToolKits.showErrorMessage(LiveActivity.this, "SaveRealData " + res.getString(R.string.info_failed));
                    } else {
                        bRecordFlag = true;
                        m_btStartRecord.setText(R.string.live_activity_stop);
                    }
                }
            } else {
                INetSDK.StopSaveRealData(lRealHandle);
                bRecordFlag = false;
                m_btStartRecord.setText(R.string.live_activity_start);
            }
        }
    }

    private void soundControl() {
        if (0 != lRealHandle) {
            if (bSound) {
                int ret = IPlaySDK.PLAYStopSoundShare(nPort);
//                m_btSound.setText(R.string.live_activity_open_sound);
                m_btSound.setBackground(getResources().getDrawable(R.drawable.ic_sound_stop_blue));
                bSound = false;
            } else {
                int ret = IPlaySDK.PLAYPlaySoundShare(nPort);
//                m_btSound.setText(R.string.live_activity_close_sound);
                m_btSound.setBackground(getResources().getDrawable(R.drawable.ic_sound_stop_write));

                bSound = true;

                if (-1 == nCurVolume) {
                    nCurVolume = IPlaySDK.PLAYGetVolume(nPort);
                } else {
                    IPlaySDK.PLAYSetVolume(nPort, nCurVolume);
                }
            }
        }
    }

    private void capture() {
        if (0 != lRealHandle) {
            if (createFile("/mnt/sdcard/NetSDK/", "local.bmp")) {
                int nRet = IPlaySDK.PLAYCatchPicEx(nPort, "/mnt/sdcard/NetSDK/local.bmp", Constants.PicFormat_BMP);
                if (0 != nRet) {
                    ToolKits.showMessage(this, res.getString(R.string.info_success));
                    return;
                }
            }
        }
        ToolKits.showMessage(this, res.getString(R.string.info_failed));
    }

    private void snap() {
        if (!bSnapCbSet) {
            TestfSnapRev stCb = new TestfSnapRev();
            INetSDK.SetSnapRevCallBack(stCb);
            bSnapCbSet = true;
        }
        SNAP_PARAMS stSnapParam = new SNAP_PARAMS();
        stSnapParam.Channel = m_nGlobalChn;
        stSnapParam.Quality = 3;
        stSnapParam.ImageSize = 1;
        stSnapParam.mode = 0;
        stSnapParam.InterSnap = 5;
        stSnapParam.CmdSerial = 100;
        if (INetSDK.SnapPictureEx(m_loginHandle, stSnapParam)) {
            ToolKits.showMessage(this, res.getString(R.string.info_success));
            return;
        }
        ToolKits.showMessage(this, res.getString(R.string.info_failed));
    }

    private void setVolume() {
        if (null != m_popFlash && m_popFlash.isShowing()) {
            m_popFlash.dismiss();
        }

        if (null != m_popPtz && m_popPtz.isShowing()) {
            m_popPtz.dismiss();
        }

        if (null != m_popQuality && m_popQuality.isShowing()) {
            m_popQuality.dismiss();
        }

        if (0 != lRealHandle) {
            if (null == m_popVolume) {
                m_popVolume = new PopupWindow(m_LayoutVolume, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
            }

            if (m_popVolume.isShowing()) {
                m_popVolume.dismiss();
                return;
            } else {
                m_popVolume.showAtLocation(findViewById(R.id.live_view), Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 150);
            }

            SeekBar m_sbVolume = (SeekBar) m_LayoutVolume.findViewById(R.id.sb_volume);
            m_sbVolume.setMax(100);
            m_sbVolume.incrementProgressBy(1);

            int nVol = IPlaySDK.PLAYGetVolume(nPort);
            m_sbVolume.setProgress(nVol);

            m_sbVolume.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
                @Override
                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                    if (fromUser) {
                        IPlaySDK.PLAYSetVolume(nPort, progress);
                        nCurVolume = progress;
                    }
                }

                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {

                }

                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {

                }
            });
        }
    }

    private void setQuality() {
        ToolKits.showMessage(this, res.getString(R.string.info_local_configure));
        if (null != m_popPtz && m_popPtz.isShowing()) {
            m_popPtz.dismiss();
        }

        if (null != m_popVolume && m_popVolume.isShowing()) {
            m_popVolume.dismiss();
        }

        if (null != m_popFlash && m_popFlash.isShowing()) {
            m_popFlash.dismiss();
        }

        Integer stBright = new Integer(0);
        Integer stContrast = new Integer(0);
        Integer stSaturation = new Integer(0);
        Integer stHuen = new Integer(0);
        int nRet = IPlaySDK.PLAYGetColor(nPort, 0, stBright, stContrast, stSaturation, stHuen);
        if (0 == nRet) {
            ToolKits.writeLog("Get color failed");
            return;
        }

        if (null == m_popQuality) {
            m_popQuality = new PopupWindow(m_layoutQuality, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        }

        if (m_popQuality.isShowing()) {
            m_popQuality.dismiss();
            return;
        } else {
            m_popQuality.showAtLocation(findViewById(R.id.live_view), Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 150);
        }

        SeekBar sbBright = (SeekBar) m_layoutQuality.findViewById(R.id.sb_quality_bright);
        sbBright.setMax(128);
        sbBright.incrementProgressBy(1);
        sbBright.setProgress(stBright);
        sbBright.setOnSeekBarChangeListener(new ColorSeekBarListenner());

        SeekBar sbContrast = (SeekBar) m_layoutQuality.findViewById(R.id.sb_quality_contrast);
        sbContrast.setMax(128);
        sbContrast.incrementProgressBy(1);
        sbContrast.setProgress(stContrast);
        sbContrast.setOnSeekBarChangeListener(new ColorSeekBarListenner());

        SeekBar sbSaturation = (SeekBar) m_layoutQuality.findViewById(R.id.sb_quality_saturation);
        sbSaturation.setMax(128);
        sbSaturation.incrementProgressBy(1);
        sbSaturation.setProgress(stSaturation);
        sbSaturation.setOnSeekBarChangeListener(new ColorSeekBarListenner());

        SeekBar sbHuen = (SeekBar) m_layoutQuality.findViewById(R.id.sb_quality_huen);
        sbHuen.setMax(128);
        sbHuen.incrementProgressBy(1);
        sbHuen.setProgress(stHuen);
        sbHuen.setOnSeekBarChangeListener(new ColorSeekBarListenner());
    }

    private void setDevQuality() {
        ToolKits.showMessage(this, res.getString(R.string.info_remote_configure));
        AV_CFG_ChannelVideoColor stAvChnVideoColor = new AV_CFG_ChannelVideoColor();
        if (ToolKits.GetDevConfig(FinalVar.CFG_CMD_VIDEOCOLOR, stAvChnVideoColor, m_loginHandle, m_nGlobalChn, 10240)) {
            ToolKits.writeLog("get config CFG_CMD_VIDEOCOLOR success");
            stAvChnVideoColor.stuColor[0].nBrightness = 60;
            stAvChnVideoColor.stuColor[0].nContrast = 60;
            stAvChnVideoColor.stuColor[0].nGamma = 60;
            stAvChnVideoColor.stuColor[0].nHue = 60;
            stAvChnVideoColor.stuColor[0].nSaturation = 60;
            if (ToolKits.SetDevConfig(FinalVar.CFG_CMD_VIDEOCOLOR, stAvChnVideoColor, m_loginHandle, m_nGlobalChn, 10240)) {
                ToolKits.writeLog("set config CFG_CMD_VIDEOCOLOR success");
            } else {
                ToolKits.writeErrorLog("set config CFG_CMD_VIDEOCOLOR failed");
            }
        } else {
            ToolKits.writeErrorLog("get config CFG_CMD_VIDEOCOLOR failed");
        }
    }


    public boolean PTZControl(MotionEvent event, int nChn, int nControl, byte param1, byte param2) {
        int nAction = event.getAction();
        if ((nAction != MotionEvent.ACTION_DOWN) && (nAction != MotionEvent.ACTION_UP)) {
            return false;
        }

        boolean zRet = INetSDK.SDKPTZControl(m_loginHandle, nChn, nControl,
                param1, param2, (byte) 0, nAction == MotionEvent.ACTION_UP);

        return false;
    }

    private boolean isOnClick = false;

    public class LiveButtonsListener implements OnClickListener {
        @Override
        public void onClick(View btClick) {
            if (btClick == m_btFlash) {
                flashProcess();
            } else if (btClick == m_btPtz) {
                ptzProcess();
            } else if (btClick == m_btStartRecord) {
                StartRecord();
            } else if (btClick == m_btSound) {
                soundControl();
            } else if (btClick == m_btCapture) {
                capture();
            } else if (btClick == m_btVolume) {
                setVolume();
            } else if (btClick == m_btEncode) {
                if (!isOnClick) {
                    startTalk();
                } else {
                    stopTalk();
                }
            } else if (btClick == m_btQuality) {
                setQuality();   // setDevQuality();
            } else if (btClick == m_btSnap) {
                snap();
            }
        }
    }

    public class TestRealDataAndDisConn implements CB_fRealDataCallBackEx, CB_fRealPlayDisConnect {
        @Override
        public void invoke(long lRealHandle, int dwDataType, byte[] pBuffer,
                           int dwBufSize, int param) {
        }

        @Override
        public void invoke(long lOperateHandle, int dwEventType) {
            ToolKits.writeLog("TestpfAudioDataCallBack");
        }
    }

    public static boolean createFile(String strPath, String strFile) {
        File path = new File(strPath);
        if (!path.exists()) {
            try {
                if (!path.mkdirs()) {
                    ToolKits.writeLog("App can't create path " + strPath);
                    return false;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        File file = new File(strPath + strFile);
        if (file.exists()) {
            file.delete();
        }

        try {
            if (!file.createNewFile()) {
                ToolKits.writeLog("App can't create file " + strPath + strFile);
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return true;
    }

    public class TestfSnapRev implements CB_fSnapRev {
        @Override
        public void invoke(long lLoginID, byte pBuf[], int RevLen, int EncodeType, int CmdSerial) {
            ToolKits.writeLog("TestfSnapRev");
            String strFileName = "";
            if (10 == EncodeType) { // ��ʾjpegͼƬ
                if (createFile("/mnt/sdcard/NetSDK/", "remote.jpg")) {
                    strFileName = "/mnt/sdcard/NetSDK/remote.jpg";
                }
            } else if (0 == EncodeType) { // mpeg4��i֡
                if (createFile("/mnt/sdcard/NetSDK/", "remote.mpeg4")) {
                    strFileName = "/mnt/sdcard/NetSDK/remote.mpeg4";
                }
            } else {
                return;
            }

            if ("" != strFileName) {
                FileOutputStream fileStream;
                try {
                    fileStream = new FileOutputStream(strFileName, true);
                    fileStream.write(pBuf, 0, RevLen);
                    fileStream.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private class ColorSeekBarListenner implements OnSeekBarChangeListener {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            if (fromUser) {
                Integer stValue[] = new Integer[4];
                for (int i = 0; i < 4; i++) {
                    stValue[i] = new Integer(0);
                }

                int nRet = IPlaySDK.PLAYGetColor(nPort, 0, stValue[0], stValue[1], stValue[2], stValue[3]);
                if (seekBar == (SeekBar) m_layoutQuality.findViewById(R.id.sb_quality_bright)) {
                    nRet = IPlaySDK.PLAYSetColor(nPort, 0, progress, stValue[1], stValue[2], stValue[3]);
                } else if (seekBar == (SeekBar) m_layoutQuality.findViewById(R.id.sb_quality_contrast)) {
                    nRet = IPlaySDK.PLAYSetColor(nPort, 0, stValue[0], progress, stValue[2], stValue[3]);
                } else if (seekBar == (SeekBar) m_layoutQuality.findViewById(R.id.sb_quality_saturation)) {
                    nRet = IPlaySDK.PLAYSetColor(nPort, 0, stValue[0], stValue[1], progress, stValue[3]);
                } else if (seekBar == (SeekBar) m_layoutQuality.findViewById(R.id.sb_quality_huen)) {
                    nRet = IPlaySDK.PLAYSetColor(nPort, 0, stValue[0], stValue[1], stValue[2], progress);
                }
            }
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    }

    @Override
    protected void onDestroy() {
        if (null != m_popFlash && m_popFlash.isShowing()) {
            m_popFlash.dismiss();
        }

        if (null != m_popPtz && m_popPtz.isShowing()) {
            m_popPtz.dismiss();
        }

        if (null != m_popVolume && m_popVolume.isShowing()) {
            m_popVolume.dismiss();
        }

        if (lRealHandle != 0) {
            StopRealPlay();
        }

        INetSDK.Cleanup();
        super.onDestroy();
    }

    long m_loginHandle = 0;
    NET_DEVICEINFO deviceInfo;
    boolean m_speedCtrl;
    int m_schedule;
    int nStreaMask = 0;

    private SDKDEV_DSP_ENCODECAP_EX stEncodeCapOld = new SDKDEV_DSP_ENCODECAP_EX();
    private CFG_DSPENCODECAP_INFO stEncodeCapNew = new CFG_DSPENCODECAP_INFO();
    private CFG_CAP_ALARM_INFO stCfgCapAlarm = new CFG_CAP_ALARM_INFO();
    private int nSpecCap = 20;

    private void login() {
        if (m_loginHandle != 0) {
            INetSDK.Logout(m_loginHandle);
            m_loginHandle = 0;
        }

        deviceInfo = new NET_DEVICEINFO();
        Integer error = new Integer(0);

        DeviceReConnect reConnect = new DeviceReConnect();
        INetSDK.SetAutoReconnect(reConnect);

        DeviceSubDisConnect subDisConnect = new DeviceSubDisConnect();
        INetSDK.SetSubconnCallBack(subDisConnect);

        INetSDK.SetDVRMessCallBack(new Test_CB_fMessageCallBack());

        String strIp = "182.40.63.114";
        String strPort = "37777";
        String strUser = "admin";
        String strPassword = "admin";

        nDevPort = 37777;
        try {
            nDevPort = Integer.parseInt(strPort);
        } catch (Exception e) {
            e.printStackTrace();
            ToolKits.showMessage(this, res.getString(R.string.login_activity_port_err));
            return;
        }
        m_loginHandle = INetSDK.LoginEx(strIp, nDevPort,
                strUser, strPassword, nSpecCap, null, deviceInfo, error);


        if (m_loginHandle != 0) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Looper.prepare();
                    // stream Type
                    if (INetSDK.QueryDevState(m_loginHandle, FinalVar.SDK_DEVSTATE_DSP_EX, stEncodeCapOld, 3000)) {
                        nStreaMask = stEncodeCapOld.dwStreamCap;
                    } else if (ToolKits.GetDevConfig(FinalVar.CFG_CMD_HDVR_DSP, stEncodeCapNew, m_loginHandle, m_nGlobalChn, 1024 * 70)) {
                        nStreaMask = stEncodeCapNew.dwStreamCap;
                    }

                    Looper.loop();
                }
            }).start();

//            ToolKits.showMessage(this, res.getString(R.string.login_activity_login_success));

            NET_IN_MEMBERNAME inMember = new NET_IN_MEMBERNAME();
            inMember.szCommand = new String();
            NET_OUT_MEMBERNAME outMember = new NET_OUT_MEMBERNAME(50, 260);
            boolean zMemberRet = INetSDK.GetMemberNames(m_loginHandle, inMember, outMember, 3000);

            m_speedCtrl = false;
            m_schedule = 0;
            SDK_DEV_ENABLE_INFO stEnableInfo = new SDK_DEV_ENABLE_INFO();
            if (INetSDK.QuerySystemInfo(m_loginHandle, SDK_SYS_ABILITY.ABILITY_DEVALL_INFO, stEnableInfo, 3000)) {
                if (stEnableInfo.IsFucEnable[SDK_DEV_FUNC.EN_PLAYBACK_SPEED_CTRL] != 0) {
                    m_speedCtrl = true;
                }

                m_schedule = stEnableInfo.IsFucEnable[SDK_DEV_FUNC.EN_SCHEDULE];
            }

            stCfgCapAlarm = new CFG_CAP_ALARM_INFO();
            char szOutBuffer[] = new char[10240];
            Integer stError = new Integer(0);
            boolean bQN = INetSDK.QueryNewSystemInfo(m_loginHandle, FinalVar.CFG_CAP_ALARM, 0, szOutBuffer, stError, 5000);
            if (bQN) {
                bQN = INetSDK.ParseData(FinalVar.CFG_CAP_ALARM, szOutBuffer, stCfgCapAlarm, null);
                if (!bQN) {
                    ToolKits.writeErrorLog("INetSDK.ParseData CFG_CAP_ALARM error");
                }
            } else {
                ToolKits.writeErrorLog("INetSDK.QueryNewSystemInfo CFG_CAP_ALARM error");
            }

            // deviceInfo
            nExtraChnNum = deviceInfo.byChanNum;
            if (-1 == deviceInfo.byChanNum) {
                SDK_PRODUCTION_DEFNITION stDef = new SDK_PRODUCTION_DEFNITION();
                boolean bRet = INetSDK.QueryProductionDefinition(m_loginHandle, stDef, 3000);
                if (bRet) {
                    nExtraChnNum = stDef.nVideoInChannel + stDef.nMaxRemoteInputChannels;
                }
            }
//            byte nExtraAlarmOutPortNum = deviceInfo.byAlarmOutPortNum;

        } else {
            System.out.println(error);
//            ToolKits.showErrorMessage(this, res.getString(R.string.login_activity_login_failed));
        }
    }

    public class DeviceDisConnect implements CB_fDisConnect {
        @Override
        public void invoke(long lLoginID, String pchDVRIP, int nDVRPort) {
        }
    }

    public class DeviceReConnect implements CB_fHaveReConnect {
        @Override
        public void invoke(long lLoginID, String pchDVRIP, int nDVRPort) {
        }
    }

    public class DeviceSubDisConnect implements CB_fSubDisConnect {
        @Override
        public void invoke(int emInterfaceType, boolean bOnline,
                           long lOperateHandle, long lLoginID) {

            ToolKits.writeLog("Device SubConnect DisConnect");
        }
    }

    class Test_CB_fMessageCallBack implements CB_fMessageCallBack {
        @Override
        public boolean invoke(int lCommand, long lLoginID, Object obj, String pchDVRIP, int nDVRPort) {
            ToolKits.writeLog("Event: " + lCommand);
            if (12295 == lCommand) {
                DEV_PLAY_RESULT stResult = (DEV_PLAY_RESULT) obj;
                ToolKits.writeLog("ResultCode: " + stResult.dwResultCode + ", PlayHandle: " + stResult.lPlayHandle);
            }
            return true;
        }
    }

    long m_TalkHandle = 0;
    boolean m_bRecordStatus = false;

    SDKDEV_TALKFORMAT_LIST m_TalkFormatList = new SDKDEV_TALKFORMAT_LIST();

    int nCurType = 1;
    boolean m_bOpenAudioRecord = false;

    long m_aacHandle = 0;
    long m_amrHandle = 0;


    void startTalk() {
        if (m_TalkFormatList.type[nCurType].encodeType == SDK_TALK_CODING_TYPE.SDK_TALK_AAC) {
            m_aacHandle = ICodecSDK.AACEncInit();
            if (0 == m_aacHandle) {
                ToolKits.showMessage(this, "AACEncInit " + res.getString(R.string.info_failed));
                return;
            }

            AAC_ENC_Format stFormatAac = new AAC_ENC_Format();
            stFormatAac.frequency = m_TalkFormatList.type[nCurType].dwSampleRate;
            stFormatAac.channels = 2;
            stFormatAac.bitRate = 64000;
            m_aacHandle = ICodecSDK.AACEncSetFormat(stFormatAac, m_aacHandle);
            if (0 == m_aacHandle) {
                ToolKits.showMessage(this, "AACEncSetFormat " + res.getString(R.string.info_failed));
                return;
            }
        }

        if (m_TalkFormatList.type[nCurType].encodeType == SDK_TALK_CODING_TYPE.SDK_TALK_AMR) {
            m_amrHandle = ICodecSDK.amrEncInit();
            if (0 == m_amrHandle) {
                ToolKits.showMessage(this, "amrEncInit " + res.getString(R.string.info_failed));
                return;
            }

            Setformat stFormatAmr = new Setformat();
            stFormatAmr.outbits = 0;
            stFormatAmr.dtx = 1;
            if (0 != ICodecSDK.amrEncSetFormat(m_amrHandle, stFormatAmr)) {
                ToolKits.showMessage(this, "amrEncSetFormat" + res.getString(R.string.info_failed));
                return;
            }
        }

        //Set Talk Code Type
        if (false == INetSDK.SetDeviceMode(m_loginHandle, EM_USEDEV_MODE.SDK_TALK_ENCODE_TYPE,
                m_TalkFormatList.type[nCurType])) {
            ToolKits.showErrorMessage(this, "SetDeviceMode SDK_TALK_ENCODE_TYPE " + res.getString(R.string.info_failed));
            return;
        }
        ToolKits.writeLog("Set Code Type Success");

        if (false == INetSDK.SetDeviceMode(m_loginHandle, EM_USEDEV_MODE.SDK_TALK_SERVER_MODE, null)) {
            ToolKits.showErrorMessage(this, "SetDeviceMode SDK_TALK_SERVER_MODE " + res.getString(R.string.info_failed));
            return;
        }
        ToolKits.writeLog("Set Server Mode Success");

        NET_TALK_TRANSFER_PARAM stTalkTransf = new NET_TALK_TRANSFER_PARAM();
        if (false == INetSDK.SetDeviceMode(m_loginHandle, EM_USEDEV_MODE.SDK_TALK_TRANSFER_MODE, stTalkTransf)) {
            ToolKits.showErrorMessage(this, "SetDeviceMode SDK_TALK_TRANSFER_MODE " + res.getString(R.string.info_failed));
            return;
        }
        ToolKits.writeLog("Set Transfer Mode Success");

        //Set Speak Mode
        NET_SPEAK_PARAM stSpeakParam = new NET_SPEAK_PARAM();
        stSpeakParam.nSpeakerChannel = 0;
        stSpeakParam.nMode = 0;
        stSpeakParam.nEnableWait = 0;

        if (false == INetSDK.SetDeviceMode(m_loginHandle, EM_USEDEV_MODE.SDK_TALK_SPEAK_PARAM,
                stSpeakParam)) {
            ToolKits.showErrorMessage(this, "SetDeviceMode SDK_TALK_SPEAK_PARAM " + res.getString(R.string.info_failed));
            return;
        }
        ToolKits.writeLog("Set Speak Mode Success");

        //Start Talk
        AudioDataCallBack audiaDatacb = new AudioDataCallBack();
        m_TalkHandle = INetSDK.StartTalkEx(m_loginHandle, audiaDatacb);
        if (0 != m_TalkHandle) {
            //	Then enbale local record function.(Does not call it if it is a one-direction audio talk.)
            //netsdk.RecordStart();
            boolean bSuccess = StartAudioRecord();
            if (bSuccess) {
                m_bOpenAudioRecord = true;
//                m_btEncode.setEnabled(false);
//                bt_end_talk.setEnabled(true);
                m_btEncode.setBackground(getResources().getDrawable(R.drawable.ic_mk_open));
                isOnClick = true;
                m_bRecordStatus = true;
            } else {
                m_btEncode.setBackground(getResources().getDrawable(R.drawable.ic_mk_close));
                isOnClick = false;
                INetSDK.StopTalkEx(m_TalkHandle);
                ToolKits.showErrorMessage(this, "StartAudioRecord " + res.getString(R.string.info_failed));
            }
        } else {
            ToolKits.showErrorMessage(this, "StartTalkEx " + res.getString(R.string.info_failed));
            ToolKits.writeErrorLog("Open talk failed!");
        }
    }

    void stopTalk() {
        if (m_bOpenAudioRecord) {
            boolean bSuccess = IPlaySDK.PLAYCloseAudioRecord() == 0 ? false : true;
            if (bSuccess) {
                m_bOpenAudioRecord = false;
                IPlaySDK.PLAYStop(100);
                IPlaySDK.PLAYStop(99);
                IPlaySDK.PLAYStopSoundShare(100);
                IPlaySDK.PLAYStopSoundShare(99);
                IPlaySDK.PLAYCloseStream(100);
                IPlaySDK.PLAYCloseStream(99);
            }
        }

        if (m_bRecordStatus) {
            //Stop local record
            //netsdk.RecordStop();
            m_bRecordStatus = false;
        }

        if (0 != m_TalkHandle) {
            //Stop audio talk to the device
            boolean bSuccess = INetSDK.StopTalkEx(m_TalkHandle);
            if (bSuccess) {
                m_TalkHandle = 0;
//                m_btEncode.setEnabled(true);
//                bt_end_talk.setEnabled(false);
                m_btEncode.setBackground(getResources().getDrawable(R.drawable.ic_mk_close));
                isOnClick = false;
            } else {
                ToolKits.showErrorMessage(this, "StopTalkEx " + res.getString(R.string.info_failed));
            }
        }

        if (0 != m_aacHandle) {
            ICodecSDK.AACEncDeInit(m_aacHandle);
            m_aacHandle = 0;
        }

        if (0 != m_amrHandle) {
            ICodecSDK.amrEncDeInit(m_amrHandle);
            m_amrHandle = 0;
        }
    }

    public class AudioDataCallBack implements CB_pfAudioDataCallBack {
        @Override
        public void invoke(long lTalkHandle, byte pDataBuf[], byte byAudioFlag) {
            ToolKits.writeLog("AudioDataCallBack received " + byAudioFlag);
            if (m_TalkHandle == lTalkHandle) {
                if (1 == byAudioFlag) {
                    //It means it has received the audio data from the device.
                    int nPort = 99;
                    //For PCM format withour header , please add 128.
                    if (m_TalkFormatList.type[nCurType].encodeType == SDK_TALK_CODING_TYPE.SDK_TALK_DEFAULT) {
                        nPort = 100;
                        for (int i = 0; i < pDataBuf.length; i++) {
                            pDataBuf[i] += 128;
                        }
                    }

                    //You can use PLAY SDK to decode to get PCM and then encode to other formats if you to get a uniform formats.
                    IPlaySDK.PLAYInputData(nPort, pDataBuf, pDataBuf.length);
                }
            }
        }
    }

    boolean StartAudioRecord() {
        //	First confirm decode port.DH_TALK_DEFAULT is 100 port number and then rest is 99 port number.
        int nPort = 99;
        if (m_TalkFormatList.type[nCurType].encodeType == SDK_TALK_CODING_TYPE.SDK_TALK_DEFAULT) {
            nPort = 100;
        }

        //	Then specify frame length
        int nFrameLength = 1024;
        switch (m_TalkFormatList.type[nCurType].encodeType) {
            case SDK_TALK_CODING_TYPE.SDK_TALK_DEFAULT:
            case SDK_TALK_CODING_TYPE.SDK_TALK_PCM:
                nFrameLength = 1024;
                break;
            case SDK_TALK_CODING_TYPE.SDK_TALK_G711a:
                nFrameLength = 1280;
                break;
            case SDK_TALK_CODING_TYPE.SDK_TALK_AMR:
                nFrameLength = 320;
                break;
            case SDK_TALK_CODING_TYPE.SDK_TALK_G711u:
                nFrameLength = 320;
                break;
            case SDK_TALK_CODING_TYPE.SDK_TALK_G726:
                nFrameLength = 320;
                break;
            case SDK_TALK_CODING_TYPE.SDK_TALK_AAC:
                nFrameLength = 1024;
            default:
                break;
        }

        if (m_TalkFormatList.type[nCurType].dwSampleRate == 48000) {
            nFrameLength = 48 * 40 * 2;
        }

        boolean bRet = false;

        //	Then call PLAYSDK library to begin recording audio
        boolean bOpenRet = IPlaySDK.PLAYOpenStream(nPort, null, 0, 1024 * 1024) == 0 ? false : true;
        if (bOpenRet) {
            boolean bPlayRet = IPlaySDK.PLAYPlay(nPort, null) == 0 ? false : true;
            if (bPlayRet) {
                IPlaySDK.PLAYPlaySoundShare(nPort);
                TestAudioRecord m_audiorecordcallback = new TestAudioRecord();
                boolean bSuccess = IPlaySDK.PLAYOpenAudioRecord(m_audiorecordcallback, m_TalkFormatList.type[nCurType].nAudioBit, m_TalkFormatList.type[nCurType].dwSampleRate, nFrameLength, 0) == 0 ? false : true;
                if (bSuccess) {
                    bRet = true;
                } else {
                    IPlaySDK.PLAYStopSoundShare(nPort);
                    IPlaySDK.PLAYStop(nPort);
                    IPlaySDK.PLAYCloseStream(nPort);
                }
            } else {
                IPlaySDK.PLAYCloseStream(nPort);
            }
        }

        return bRet;
    }

    public class TestAudioRecord implements IPlaySDKCallBack.pCallFunction {
        @Override
        public void invoke(byte[] pDataBuffer, int nBufferLen, long pUserData) {
            try {
                //encode
                ToolKits.writeLog("AudioRecord send " + nBufferLen);
                byte encode[] = AudioRecord(pDataBuffer);

                //It means it is the audio data from the local m_TalkHandle
                long lSendLen = INetSDK.TalkSendData(m_TalkHandle, encode);
                if (lSendLen != (long) encode.length) {
                    //Error occurred when sending the user audio data to the device
                }

            } catch (Exception e) {
            }
        }
    }

    byte[] AudioRecord(byte[] pDataBuffer) {
        int DataLength = pDataBuffer.length;
        if (m_TalkFormatList.type[nCurType].encodeType == SDK_TALK_CODING_TYPE.SDK_TALK_DEFAULT
                || m_TalkFormatList.type[nCurType].encodeType == SDK_TALK_CODING_TYPE.SDK_TALK_PCM) {
            byte pCbData[] = null;
            pCbData = new byte[8 + DataLength];

            if (m_TalkFormatList.type[nCurType].nAudioBit == 8) {
                for (int j = 0; j < DataLength; j++) {
                    pDataBuffer[j] += 128;
                }
            }

            pCbData[0] = (byte) 0x00;
            pCbData[1] = (byte) 0x00;
            pCbData[2] = (byte) 0x01;
            pCbData[3] = (byte) 0xF0;

            pCbData[4] = (byte) (m_TalkFormatList.type[nCurType].nAudioBit == 8 ? 0x07 : 0x0C);
            if (8000 == m_TalkFormatList.type[nCurType].dwSampleRate) {
                pCbData[5] = 0x02;//8k
            } else if (16000 == m_TalkFormatList.type[nCurType].dwSampleRate) {
                pCbData[5] = 0x04;
            } else if (48000 == m_TalkFormatList.type[nCurType].dwSampleRate) {
                pCbData[5] = 0x09;
            } else if (32000 == m_TalkFormatList.type[nCurType].dwSampleRate) {
                pCbData[5] = 0x07;
            }
            pCbData[6] = (byte) (DataLength & 0x00FF);
            pCbData[7] = (byte) (DataLength >> 8);
            System.arraycopy(pDataBuffer, 0, pCbData, 8, DataLength);
            return pCbData;
        } else if (m_TalkFormatList.type[nCurType].encodeType == SDK_TALK_CODING_TYPE.SDK_TALK_G711a) {
            byte pbOut[] = new byte[102400];
            int iCbLen = INetSDK.g711aEncode(pDataBuffer, pbOut, DataLength);

            byte pCbData[] = null;
            pCbData = new byte[iCbLen + 8];

            // bit stream format frame head
            pCbData[0] = 0x00;
            pCbData[1] = 0x00;
            pCbData[2] = 0x01;
            pCbData[3] = (byte) 0xF0;

            pCbData[4] = 0x0E; //G711A
            if (8000 == m_TalkFormatList.type[nCurType].dwSampleRate) {
                pCbData[5] = 0x02;//8k
            } else if (16000 == m_TalkFormatList.type[nCurType].dwSampleRate) {
                pCbData[5] = 0x04;
            } else if (48000 == m_TalkFormatList.type[nCurType].dwSampleRate) {
                pCbData[5] = 0x09;
            } else if (32000 == m_TalkFormatList.type[nCurType].dwSampleRate) {
                pCbData[5] = 0x07;
            }
            pCbData[6] = (byte) (iCbLen & 0xff);
            pCbData[7] = (byte) (iCbLen >> 8);
            System.arraycopy(pbOut, 0, pCbData, 8, iCbLen);
            return pCbData;
        } else if (m_TalkFormatList.type[nCurType].encodeType == SDK_TALK_CODING_TYPE.SDK_TALK_G711u) {
            byte pbOut[] = new byte[102400];
            int iCbLen = INetSDK.g711uEncode(pDataBuffer, pbOut, DataLength);

            byte pCbData[] = null;
            pCbData = new byte[iCbLen + 8];

            // bit stream format frame head
            pCbData[0] = 0x00;
            pCbData[1] = 0x00;
            pCbData[2] = 0x01;
            pCbData[3] = (byte) 0xF0;

            pCbData[4] = 0x0A; //G711u
            if (8000 == m_TalkFormatList.type[nCurType].dwSampleRate) {
                pCbData[5] = 0x02;//8k
            } else if (16000 == m_TalkFormatList.type[nCurType].dwSampleRate) {
                pCbData[5] = 0x04;
            } else if (48000 == m_TalkFormatList.type[nCurType].dwSampleRate) {
                pCbData[5] = 0x09;
            } else if (32000 == m_TalkFormatList.type[nCurType].dwSampleRate) {
                pCbData[5] = 0x07;
            }
            pCbData[6] = (byte) (iCbLen & 0xff);
            pCbData[7] = (byte) (iCbLen >> 8);
            System.arraycopy(pbOut, 0, pCbData, 8, iCbLen);
            return pCbData;
        } else if (m_TalkFormatList.type[nCurType].encodeType == SDK_TALK_CODING_TYPE.SDK_TALK_AMR) {
            // code haven't been debug
            //AMR encode
            byte pbOut[] = new byte[102400];

            AudioBuf stBuf = new AudioBuf();
            stBuf.pData = pDataBuffer;
            stBuf.channels = 1;
            stBuf.offset = 2;
            stBuf.depth = 16;
            stBuf.dataLen = pDataBuffer.length;
            stBuf.frequency = m_TalkFormatList.type[nCurType].dwSampleRate;
            Integer nOutlen = new Integer(0);
            int nRet = ICodecSDK.amrEncEncode(m_amrHandle, stBuf, pbOut, nOutlen);
            if ((0 == nRet)
                    || (nOutlen.intValue() > 0)) {
                int iCbLen = nOutlen.intValue();
                byte pCbData[] = null;
                pCbData = new byte[iCbLen + 8];

                pCbData[0] = 0x00;
                pCbData[1] = 0x00;
                pCbData[2] = 0x01;
                pCbData[3] = (byte) 0xF0;

                pCbData[4] = 0x14; //AMR
                if (8000 == m_TalkFormatList.type[nCurType].dwSampleRate) {
                    pCbData[5] = 0x02;//8k
                } else if (16000 == m_TalkFormatList.type[nCurType].dwSampleRate) {
                    pCbData[5] = 0x04;
                } else if (48000 == m_TalkFormatList.type[nCurType].dwSampleRate) {
                    pCbData[5] = 0x09;
                } else if (32000 == m_TalkFormatList.type[nCurType].dwSampleRate) {
                    pCbData[5] = 0x07;
                }

                pCbData[6] = (byte) (iCbLen & 0xff);
                pCbData[7] = (byte) (iCbLen >> 8);

                System.arraycopy(pbOut, 0, pCbData, 8, iCbLen);
                return pCbData;
            }
        } else if (m_TalkFormatList.type[nCurType].encodeType == SDK_TALK_CODING_TYPE.SDK_TALK_AAC) {
            // code haven't been debug
            byte outBuf[] = new byte[DataLength * 2];

            int i = 0;
            for (i = (DataLength / 2 - 1); i >= 0; i--) {
                outBuf[4 * i] = pDataBuffer[2 * i];
                outBuf[4 * i + 1] = pDataBuffer[2 * i + 1];
                outBuf[4 * i + 2] = pDataBuffer[2 * i];
                outBuf[4 * i + 3] = pDataBuffer[2 * i + 1];
            }

            //AAC encode
            if (m_aacHandle != 0) {
                byte pbOut[] = new byte[102400];

                Integer nOutlen = new Integer(0);
                AudioBuf stBuf = new AudioBuf();
                stBuf.pData = outBuf;
                stBuf.channels = 2;
                stBuf.offset = 4;
                stBuf.depth = 16;
                stBuf.dataLen = outBuf.length;
                stBuf.frequency = m_TalkFormatList.type[nCurType].dwSampleRate;
                int nRet = ICodecSDK.AACEncEncode(m_aacHandle, stBuf, pbOut, nOutlen);
                if ((0 == nRet)
                        && (nOutlen.intValue() > 0)) {
                    int iCbLen = nOutlen.intValue();
                    byte pCbData[] = null;
                    pCbData = new byte[iCbLen + 8];

                    pCbData[0] = 0x00;
                    pCbData[1] = 0x00;
                    pCbData[2] = 0x01;
                    pCbData[3] = (byte) 0xF0;

                    pCbData[4] = 0x1A; //AAC
                    if (8000 == m_TalkFormatList.type[nCurType].dwSampleRate) {
                        pCbData[5] = 0x02;//8k
                    } else if (16000 == m_TalkFormatList.type[nCurType].dwSampleRate) {
                        pCbData[5] = 0x04;
                    } else if (48000 == m_TalkFormatList.type[nCurType].dwSampleRate) {
                        pCbData[5] = 0x09;
                    } else if (32000 == m_TalkFormatList.type[nCurType].dwSampleRate) {
                        pCbData[5] = 0x07;
                    }

                    pCbData[6] = (byte) (iCbLen & 0xff);
                    pCbData[7] = (byte) (iCbLen >> 8);

                    System.arraycopy(pbOut, 0, pCbData, 8, iCbLen);
                    return pCbData;
                }
            }
        }

        return null;
    }

}